﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package reprise.css.math {

    public class CSSCalculationGroup extends AbstractCSSCalculation {

        protected var m_operation:Function;
        protected var m_operator:String;
        protected var m_operand1:Object;
        protected var m_operand2:Object;

        public static const OPERATOR_PLUS:String = "+";
        public static const OPERATOR_MULTIPLY:String = "*";
        public static const OPERATOR_MODULO:String = "mod";
        public static const OPERATOR_DIVIDE:String = "/";
        public static const OPERATOR_MINUS:String = "-";

        protected static var g_operations:Object = initializeOperations();
        protected static var g_tokenizer:RegExp = /(?<!\w)binding(?=\(\()|(?<=(?<!\w)binding)\(\(\s*[\w_\-.:#\[\] ]+\s*,\s*[\w_]+\s*\)\)|(?<=\d)pt|(?<=\d)px|[()]|mod|[+\-*\/]|(?<!\w)[0-9.][0-9.exEX]*|%/g;

        public function CSSCalculationGroup(_arg1:String, _arg2:Object, _arg3:Object){
            setOperator(_arg1);
            m_operand1 = _arg2;
            m_operand2 = _arg3;
        }
        override public function resolve(_arg1:Number, _arg2:ICSSCalculationContext=null):Number{
            var _local3:Number = ((m_operand1 is Number)) ? (m_operand1 as Number) : AbstractCSSCalculation(m_operand1).resolve(_arg1, _arg2);
            var _local4:Number = ((m_operand2 is Number)) ? (m_operand2 as Number) : AbstractCSSCalculation(m_operand2).resolve(_arg1, _arg2);
            var _local5:Number = m_operation(_local3, _local4);
            return (_local5);
        }
        public function setOperator(_arg1:String):void{
            m_operator = _arg1;
            m_operation = g_operations[_arg1];
        }
        public function setOperand2(_arg1:Object):void{
            m_operand2 = _arg1;
        }
        public function toString():String{
            return ((((((("CSSCalculationGroup: operator " + m_operator) + ", operand1 (") + m_operand1.toString()) + "), operand2 (") + m_operand2.toString()) + ")"));
        }
        public function setOperand1(_arg1:Object):void{
            m_operand1 = _arg1;
        }

        protected static function operationDivide(_arg1:Number, _arg2:Number):Number{
            return ((_arg1 / _arg2));
        }
        protected static function operationMinus(_arg1:Number, _arg2:Number):Number{
            return ((_arg1 - _arg2));
        }
        protected static function initializeOperations():Object{
            var _local1:Object = {};
            _local1["+"] = operationPlus;
            _local1["-"] = operationMinus;
            _local1["*"] = operationMultiply;
            _local1["/"] = operationDivide;
            _local1["mod"] = operationModulo;
            _local1["^"] = operationPow;
            return (_local1);
        }
        protected static function operationPlus(_arg1:Number, _arg2:Number):Number{
            return ((_arg1 + _arg2));
        }
        protected static function reduce(_arg1:Array, _arg2:Array):void{
            var _local3:Object = _arg2[(_arg2.length - 2)];
            var _local4:Object = _arg2[(_arg2.length - 1)];
            _arg2.length = (_arg2.length - 2);
            _arg2.push(new CSSCalculationGroup(String(_arg1.pop()), _local3, _local4));
        }
        protected static function operationMultiply(_arg1:Number, _arg2:Number):Number{
            return ((_arg1 * _arg2));
        }
        protected static function parse(_arg1:String):CSSCalculationGroup{
            var _local5:String;
            var _local2:Array = tokenize(_arg1);
            var _local3:Array = [];
            var _local4:Array = [];
            while (_local2.length) {
                _local5 = String(_local2.shift());
                switch (_local5){
                    case "(":
                        _local3.push(_local5);
                        break;
                    case ")":
                        while (_local3[(_local3.length - 1)] != "(") {
                            reduce(_local3, _local4);
                        };
                        _local3.pop();
                        break;
                    case "^":
                    case "*":
                    case "/":
                    case "mod":
                    case "+":
                    case "-":
                        if (_local3[(_local3.length - 1)] != "("){
                            reduce(_local3, _local4);
                        };
                        _local3.push(_local5);
                        break;
                    case "binding":
                        _local5 = _local2.shift();
                        _local4.push(new CSSCalculationBinding(_local5));
                        break;
                    default:
                        if (_local2[0] == "%"){
                            _local4.push(new CSSCalculationPercentage(_local5));
                            _local2.shift();
                        } else {
                            _local4.push(parseFloat(_local5));
                            if ((((_local2[0] == "px")) || ((_local2[0] == "pt")))){
                                _local2.shift();
                            };
                        };
                };
            };
            if (!(_local4[0] is CSSCalculationGroup)){
                return (new CSSCalculationGroup(CSSCalculationGroup.OPERATOR_PLUS, _local4[0], 0));
            };
            return (_local4[0]);
        }
        protected static function operationPow(_arg1:Number, _arg2:Number):Number{
            return (Math.pow(_arg1, _arg2));
        }
        public static function PrepareCalculation(_arg1:String):CSSCalculationGroup{
            return (parse(_arg1));
        }
        protected static function tokenize(_arg1:String):Array{
            var _local4:Array;
            var _local5:String;
            _arg1 = _arg1.replace(/\s*([+\-*\^()])\s*/g, "$1");
            _arg1 = (("(((" + _arg1.split("(").join("((").split(")").join("))")) + ")))");
            var _local2 = 100;
            var _local3:Array = [];
            while ((((_local4 = g_tokenizer.exec(_arg1))) && (_local2))) {
                _local5 = _local4[0];
                switch (_local5){
                    case "^":
                    case "*":
                    case "/":
                    case "mod":
                        _local3.push(")");
                        _local3.push(_local5);
                        _local3.push("(");
                        break;
                    case "+":
                    case "-":
                        _local3.push(")");
                        _local3.push(")");
                        _local3.push(_local5);
                        _local3.push("(");
                        _local3.push("(");
                        break;
                    case null:
                        break;
                    default:
                        _local3.push(_local5);
                };
            };
            return (_local3);
        }
        protected static function operationModulo(_arg1:Number, _arg2:Number):Number{
            return ((_arg1 % _arg2));
        }

    }
}//package reprise.css.math 
